/**
 * @file icon-button
 * @author liaoxuezhi@baidu.com
 */
/* eslint fecs-indent: [0, "space", 2, 2] */

import * as React from 'react';
import {
  PureComponent,
  PropTypes
} from 'react';
import {Renderer, render, renderChildren, evalExpression} from './renderer';
import * as cx from 'classnames';
import * as CustomPropTypes from './propTypes';
import * as omit from 'lodash/omit';
import {
  Tabs,
  Tab
} from 'react-bootstrap';
import * as schema from './tabs-schema.json'

@Renderer({
  name: 'tabs',
  desc: '...',
  test: (path, config) => /(?:^|\/)tabs$/.test(path),
  schema
})
export default class TabsRenderer extends PureComponent {
  static propTypes = {
    className: PropTypes.string,
    tabsClassName: PropTypes.string,
    tabs: PropTypes.arrayOf(PropTypes.shape({
      title: PropTypes.string.isRequired,
      tab: CustomPropTypes.container
    })).isRequired
  };

  static defaultProps = {
    className: '',
    tabsClassName: '',
    defaultActiveKey: 0,
    completeIcon: 'fa fa-check text-success m-l-xs',
    unCompleteIcon: 'fa fa-times text-warning m-l-xs'
  };

  lazyLoadMap = {};
  tabHashMap = {};

  constructor(props, context) {
    super(props, context);

    

    this.generateHashMap(props);

    this.state = {
      key: this.generateActiveKey(props)
    };

    this.lazyLoadMap[this.state.key] = true;

    this.handleSelect = this.handleSelect.bind(this);
  }

  generateActiveKey(props) {
    const location = props.location;
    if (!location || !location.hash) {
      return this.state && this.state.key || props.defaultActiveKey;
    }
    const key1 = this.tabHashMap[location.hash.substring(1)];
    const key2 = this.state && this.state.key;
    const key3 = props.defaultActiveKey;
    return key1 !== void 0 ? key1 : key2 !== void 0 ? key2 : key3 !== void 0 ? key3 : 0;
  }

  componentWillReceiveProps(nextProps) {
    const prevLocation = this.props.location;
    const nextLocation = nextProps.location;
    if (this.props.tabs != nextProps.tabs) {
      this.generateHashMap(nextProps);
    }

    if (prevLocation && nextLocation && prevLocation.hash != nextLocation.hash) {
      let key = this.generateActiveKey(nextProps);
      this.lazyLoadMap[key] = true;
      this.setState({
        key
      });
    }
  }

  generateHashMap(props) {
    const tabs = props.tabs;
    if (tabs && Array.isArray(tabs)) {
      tabs.forEach(({hash}, key) => {
        hash && (this.tabHashMap[hash] = key);
      });
    }
  }

  handleSelect(key) {
    const tabs = this.props.tabs;
    this.lazyLoadMap[key] = true;
    this.setState({key}, () => {
      location.hash = tabs[key].hash || "";
    });
  }

  render() {
    const {
      className,
      tabs,
      tabsClassName,
      data,
      $path,
      completeIcon,
      unCompleteIcon
    } = this.props;

    return (
      <div className={cx('tabs-wrapper', className)}>
        <Tabs activeKey={this.state.key} onSelect={this.handleSelect} id={`tabs`} className={tabsClassName}>
          {tabs.map(({tab, title, toolbar, toolbarClassName, visibleOn, hiddenOn, icon, badge, complete, completeOn, reload}, key) => {
            if (visibleOn && !evalExpression(visibleOn, data)) {
              return null;
            } else if (hiddenOn && evalExpression(hiddenOn, data)) {
              return null;
            }

            if (typeof complete !== 'undefined' || completeOn) {
              let status = evalExpression(completeOn, data) || complete;
              icon = status ? completeIcon : unCompleteIcon;
            }

            const head = icon || badge ? (<div>{icon && !badge ? (<i className={icon} />) : null} {badge ? <span className={`badge ${this.state.key == key ? 'badge-info' : ''}`}>{badge.value || badge}</span> : null} {title} {icon && badge ? (<i className={icon} />) : null}</div>) : title;
            return (
              <Tab eventKey={key} title={head} key={key}>
                {toolbar && <div className={cx('tab-toolbar', toolbarClassName)}>{renderChildren($path, toolbar, omit(this.props, ['className', 'tabs', '$path', 'type']))}</div>}
                <div className={tab && tab.tabClassName || 'bg-white b-l b-r b-b wrapper-md'}>
                  {this.lazyLoadMap[key] && (!reload || this.state.key === key) ? renderChildren($path, tab, omit(this.props, ['className', 'tabs', '$path', 'type'])) : null}
                </div>
              </Tab>
            );
          })}
        </Tabs>
      </div>
    );
  }
}
